package it.crudity.web.json;

import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;

/***
 * This {@link BeanFactoryPostProcessor} implementation changes the class of
 * every {@link MappingJacksonHttpMessageConverter} bean registered in every
 * {@link AnnotationMethodHandlerAdapter} with
 * {@link FilteredMappingJacksonHttpMessageConverter}, a subclass with
 * {@link JsonFilter} support,
 * 
 * 
 * @author g.caporaletti
 * 
 */
public class JsonFilterSupportBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@SuppressWarnings("unchecked")
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		String[] adapterNames = beanFactory.getBeanNamesForType(AnnotationMethodHandlerAdapter.class);
		for (String adapter : adapterNames) {
			BeanDefinition def = beanFactory.getBeanDefinition(adapter);
			PropertyValue messageConvertersProp = def.getPropertyValues().getPropertyValue("messageConverters");
			List<RootBeanDefinition> values = (List<RootBeanDefinition>) messageConvertersProp.getValue();
			for (RootBeanDefinition converterDef : values) {
				if (converterDef.getBeanClass().equals(MappingJacksonHttpMessageConverter.class)) {
					converterDef.setBeanClassName(FilteredMappingJacksonHttpMessageConverter.class.getName());
				}
			}

		}
	}
}
